在上一篇【1】中我们介绍了 “Linuxkit 中的 kernel+initrd 镜像启动过程”,那么我们接下来看看 Linuxkit 是如何一步一步构造出 kernel +initrd 这些镜像的。
首先看一下 Moby 结构体定义,基本和 yml 中支持的属性一一对应
1 | 23 // Moby is the type of a Moby config file |
NewConfig(parse yml config 文件) –> buildInternal (实际的 build 过程) –> outputs (生成相应格式的镜像)
其中 buildInternal 的过程如下
1 | --> dockerPull --> ImageExtract --> untarKernel |
下载 Kernel 对应的 image,从对应的镜像中提取文件系统并返回一个 tar,从 tar 中提取出 kernel 、 kernel.tar 并放到新的 tar 文件中(initrdAppend 操作),tar 文件为了区分 kernel 和 其他文件,对 kernel 设置了 tar header 字段(boot/kernel boot/cmdline)
对于 Init 镜像都要解压,并且添加到上面新的tar 文件中(initrdAppend)
对于 Onboot 镜像,执行以下操作:
ConfigToOCI(image) , –> ImageBundle(对应目录为/containers/onboot/) –> 同样添加到文件中 (initrdAppend)
对于 service 镜像,执行以下操作:
ConfigToOCI(image) –》 ImageBundle(对应目录为 /containers/services/) –> 同样添加到文件中 (initrdAppend )
最后是添加一些额外的文件,程序需要的,比如 ssh key 文件(initrdAppend)
–> outputs
按照 yml 中的输出格式,输出对应的文件,这里以 kernel+initrd 举例
输出对应的 kernel + initrd 文件,其中 kernel 和 initrd 是在前面的 tar 包装的时候,都有设置了对应的 tar header,所以可以从一个文件中抽取出 kernel,剩下的就是 initrd 文件
对于其他虚拟机镜像格式,其实就是讲对应的 kernel + initrd 打包成对应的镜像格式比如 qcow2
那么对于上述构造的 VM 镜像,里面的容器如何自动运行起来的。那么我们就需要理解前面讲的 kernel +initrd 的启动过程,在 BIOS 自检后,bootloder 开始加载 kernel +initramfs, 那么我们从下面将这里如何对应到 moby 构建的镜像里面的代码
initrd 上面除了包含一些 modules, 还包含 init, onboot, services 镜像,其中 kernel+ initrd 配合完成对应的真正 root 挂载后,控制权交给了/sbin/init
init 进程,开始根据 /etc/inittab 中进行进程的派生,看卡 inittab 什么样子
1 | / # cat /etc/inittab |
我们看到了熟悉的 /etc/init.d/containerd 和 /etc/init.d/containers,其中 containerd 是容器运行控制进程,首先启动。接着对于所有的containers 进行 roofs 的挂载,runc 调用运行这些容器,代码如下:
1 | / # cat /etc/init.d/containers |
通过mount 查看里面的挂载情况:
1 | tmpfs on /var type tmpfs (rw,nosuid,nodev,noexec,relatime) |
如此,就完成了 VM 启动后的容器的自动运行
参考: